package com.jtpay.payresulthelper.http.retrofit;

import android.net.ParseException;
import android.text.TextUtils;
import com.google.gson.JsonParseException;
import com.jtpay.payresulthelper.R;
import com.jtpay.payresulthelper.http.dataStructure.BasicResponse;
import com.jtpay.payresulthelper.http.listener.TransApiResultListener;
import com.jtpay.payresulthelper.util.LogUtil;
import com.jtpay.payresulthelper.util.manager.ToastUtil;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import org.json.JSONException;
import retrofit2.HttpException;

import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;

import static com.jtpay.payresulthelper.http.retrofit.RetrofitBasicResponseObserverAndListener.ExceptionReason.*;
import static com.jtpay.payresulthelper.util.PayContext.API_TASK_ERROR_COUNT_DEF;

public class RetrofitBasicResponseObserverAndListener<T extends BasicResponse, E> implements Observer<T> {
    private TransApiResultListener<E> listener;

    private int errorCount = 0;

    public TransApiResultListener<E> getListener() {
        return listener;
    }

    public void setListener(TransApiResultListener<E> listener) {
        this.listener = listener;
    }

    protected boolean isLimited() {
        return errorCount >= API_TASK_ERROR_COUNT_DEF;
    }

    private void resetErrorCount() {
        this.errorCount = 0;
    }

    protected RetrofitBasicResponseObserverAndListener() {
    }

    @Override
    public void onSubscribe(Disposable d) {
        LogUtil.log("onSubscribe = " + d.toString());
    }

    @Override
    public void onNext(T response) {
        resetErrorCount();
        if (response.isFlag()) {
            onSuccess(response);
        } else {
            onFail(response);
        }
    }

    /**
     * 请求数据成功 且响应码为200
     *
     * @param response 服务器返回的数据
     */
    public void onSuccess(T response) {

    }

    /**
     * 服务器返回数据，但响应码不为200
     *
     * @param response 服务器返回的数据
     */
    public void onFail(T response) {
        LogUtil.log("onFail = " + response.toString());
        String message = response.getMsg();
        if (!TextUtils.isEmpty(message)) {
            ToastUtil.showShort(message);
        }
    }

    @Override
    public void onError(Throwable e) {
        LogUtil.log("RetrofitObserver onError " + e.getMessage());
        errorCount += 1;
        if (e instanceof HttpException) {     //   HTTP错误
            onException(BAD_NETWORK);
        } else if (e instanceof ConnectException
                || e instanceof UnknownHostException) {   //   连接错误
            onException(CONNECT_ERROR);
        } else if (e instanceof InterruptedIOException) {   //  连接超时
            onException(CONNECT_TIMEOUT);
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {   //  解析错误
            onException(PARSE_ERROR);
        } else {
            onException(UNKNOWN_ERROR);
        }
    }

    /**
     * 请求异常
     *
     * @param reason ExceptionReason
     */
    private void onException(ExceptionReason reason) {
        switch (reason) {
            case CONNECT_ERROR:
                ToastUtil.showShort(R.string.connect_error);
                break;
            case CONNECT_TIMEOUT:
                ToastUtil.showShort(R.string.connect_timeout);
                break;
            case BAD_NETWORK:
                ToastUtil.showShort(R.string.bad_network);
                break;
            case PARSE_ERROR:
                ToastUtil.showShort(R.string.parse_error);
                break;
            case UNKNOWN_ERROR:
            default:
                ToastUtil.showShort(R.string.unknown_error);
                break;
        }
    }

    @Override
    public void onComplete() {
        LogUtil.log("RetrofitObserverAndListener onComplete");
    }

    public enum ExceptionReason {
        CONNECT_ERROR, CONNECT_TIMEOUT, BAD_NETWORK, PARSE_ERROR, UNKNOWN_ERROR
    }
}
